package com.codeblue.tools.codeGenerator;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.com.qingz.core.model.FiledComment;
import cn.com.qingz.core.model.UIType;
import cn.com.qingz.modules.user.model.BillGoods;
import cn.com.qingz.modules.user.model.SampleHouse;
import cn.com.qingz.modules.user.model.Version;
import cn.com.qingz.modules.user.vo.BillGoodsSearchCondition;
import cn.com.qingz.modules.user.vo.ModelSearchCondition;
import cn.com.qingz.modules.user.vo.SampleHouseSearchCondition;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;


public class BusinessCodeCreater {
	public static void main(String[] args) throws IOException, TemplateException {
		
		try {
			
			System.out.println("开始生成文件---------");
			BusinessCodeCreater creater = new BusinessCodeCreater();
			Project project = new Project();
			configProjectSetting(project);
			Module shopdiscriminate = new Module();
			shopdiscriminate.setProject(project);
			shopdiscriminate.setModuleName("user");
			//创建文件夹
//			shopdiscriminate.createModuleDir();
//			 EntityDesc entity2 = new EntityDesc(skuProductDet.class,"产品Sku描述");
			 EntityDesc entity1 = new EntityDesc(SampleHouse.class,"样板间");
			 Configuration cfg = new Configuration();  
			 cfg.setDirectoryForTemplateLoading(new File(project.getTemplatePath()));  
			
			 shopdiscriminate.getEntityClass().add(entity1);
//			 shopdiscriminate.getEntityClass().add(entity2);
			 for (EntityDesc entity : shopdiscriminate.getEntityClass()) {
				 creater.genMapperInterface(cfg,shopdiscriminate,"mapperInterface.ftl",entity) ;
				 creater.genMapper(cfg,shopdiscriminate,"mapper.ftl",entity, SampleHouseSearchCondition.class);
				 creater.genSerivce(cfg,shopdiscriminate,"service.ftl",entity);
				 creater.genServiceImpl(cfg,shopdiscriminate,"serviceImpl.ftl",entity);
				 creater.genController(cfg,shopdiscriminate,"controller.ftl",entity);
//				 creater.genQueryJs(cfg, shopdiscriminate, "queryJs.ftl", entity, BillGoodsSearchCondition.class, BillGoods.class);
				 creater.genQueryJsp(cfg,shopdiscriminate,"queryjsp.ftl",entity,SampleHouseSearchCondition.class, SampleHouse.class);
			  }
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println("生成文件完成-------");
		
	}


	 /*
	 * 项目设置
	 * @param project
	 */
	private static void configProjectSetting(Project project) {
		project.setProjectName("lphome");
		
		String dir = "D:/git/lphome" ;
		project.setSrc_diskPath(dir + "/src/main/java/cn/com/qingz/modules");
		project.setJsp_disPath(dir + "/src/main/webapp/view");
		project.setJs_diskPath(dir + "/src/main/webapp/resources/js");
		project.setTemplatePath(dir +  "/src/main/java/com/codeblue/tools/codeGenerator/template");
//		project.setMapperInterfacePath("E:\\workspace\\wsq\\src\\com\\wsq\\db\\mapper  D:/qqq/qzszLogistics/src/com/wsq/common/tools/codeGen/template");
//		project.setMapperPath("E:\\workspace\\wsq\\src\\com\\wsq\\db\\sqlmap");
	}
	
	
	
	public   void genController( Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		 Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity", entity);
	     root.put("module", module.getModuleName());
	     root.put("moduleUpperName", module.getModuleName().toUpperCase());
	     
	     //输出
	     Writer out = new FileWriter(module.getControllerPath()+"\\"+ entity.getClassName()+"Controller.java");  
	     template.process(root,out);  
	     
	}
	
	public   void genMapperInterface( Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		 Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity", entity);
	     root.put("module", module.getModuleName());
	     
	    
	     
	     //输出
	     Writer out = new FileWriter(module.getMapperPath() + "\\"+ entity.getClassName()+"Mapper.java");  
	     template.process(root,out);  
	     
	}
	
	
	public void genMapper(Configuration cfg,Module module,String templateFile,EntityDesc desc,Class searchCondition) throws IOException, TemplateException{
		 Template template =  cfg.getTemplate(templateFile);  
		 
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("namespace", "com.wsq.db.mapper."+desc.getUpperName()+"Mapper");
	     root.put("entity", desc);
	     root.put("module", module.getModuleName());
	     
	     EntityDesc searchDesc = new EntityDesc(searchCondition,"");
	     root.put("searchConditionDto", searchDesc );
	     
	     
	     //输出
	     Writer out = new FileWriter(module.getMapperPath() +"\\"+ desc.getClassName() +"Mapper.xml");  
	     template.process(root,out);  	
	     
	}
	public void genSerivce(Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		 Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity", entity);
	     root.put("module", module.getModuleName());
	     
	     //输出
	     Writer out = new FileWriter(module.getServicePath()+"\\"+ entity.getClassName()+"Service.java");  
	     template.process(root,out);   
	}
	public void genServiceImpl(Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		 Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity", entity);
	     root.put("module", module.getModuleName());
	     
	     //输出
	     Writer out = new FileWriter(module.getServiceImplPath()+"\\"+ entity.getClassName()+"ServiceImpl.java");  
	     template.process(root,out);   
	}
	public void genAddJsp(Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		
		Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity",entity);
	     root.put("module", module.getModuleName());
	     
	     List<Map<String,String>> fieldList = new ArrayList<Map<String,String>>();
	   
	    Field fields[] = entity.getEntity().getDeclaredFields();
 		for (Field me : fields) {
 			Annotation[] ans = me.getAnnotations();
 			for (Annotation annotation : ans) {
 				if (annotation instanceof FiledComment) {
 				    Map<String,String> formField = new HashMap<String,String>();
 					formField.put("cn_name", ((FiledComment) annotation).value());
 					formField.put("en_name", me.getName());
 					formField.put("uiType", ((FiledComment) annotation).uiType());
 					fieldList.add(formField) ;
 				}
 			}
 		}
 		
	     root.put("fieldList", fieldList);
	     root.put("title", entity.getCnName()+"新增");
	     //输出
	     Writer out = new FileWriter(module.getJspPath()+"\\"+entity.getLowerName()+"_add.jsp");
	     template.process(root,out);  
	}
	public  void genSerachConditionDto(Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity", entity);
	     root.put("module", module.getModuleName());
	     
	     //输出
	     Writer out = new FileWriter(module.getVOPath()+"\\"+ entity.getClassName()+"SearchCondition.java");  
	     template.process(root,out);  
	}
	
	public  void genEntityDto(Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity", entity);
	     root.put("module", module.getModuleName());
	     
	     //输出
	     Writer out = new FileWriter(module.getVOPath()+"\\"+ entity.getClassName()+"Dto.java");  
	     template.process(root,out);  
	}
	
	public void genShareJS(Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity",entity);
	     root.put("module", module.getModuleName());
	     
	   
		
	     root.put("uiList", getUIComponent(entity.getEntity()));
	     //输出
	     Writer out = new FileWriter(module.getJsPath()+"\\"+entity.getLowerName()+"_share.js");
	     template.process(root,out);  
	}
	
	public void genUpdateJSp(Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity",entity);
	     root.put("module", module.getModuleName());
	     root.put("title",entity.getCnName());
	   
		
	     root.put("uiList", getUIComponent(entity.getEntity()));
	     //输出
	     Writer out = new FileWriter(module.getJspPath()+"\\"+entity.getLowerName()+"_update.jsp");
	     template.process(root,out);  
	}
	public void genDetailJSp(Configuration cfg,Module module,String templateFile,EntityDesc entity) throws IOException, TemplateException{
		Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity",entity);
	     root.put("module", module.getModuleName());
	     root.put("title",entity.getCnName());
	   
		
	     root.put("uiList", getUIComponent(entity.getEntity()));
	     //输出
	     Writer out = new FileWriter(module.getJspPath()+"\\"+entity.getLowerName()+"_detail.jsp");
	     template.process(root,out);  
	}
	
	/**
	 * 生成查询页面
	 * @param cfg
	 * @param module
	 * @param templateFile
	 * @param entity
	 * @param serachConditionDto
	 * @param entityDto
	 * @throws IOException
	 * @throws TemplateException
	 */
	public void genQueryJsp(Configuration cfg,Module module,String templateFile,EntityDesc entity,Class<?> serachConditionDto,Class<?> entityDto) throws IOException, TemplateException{
		 Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity",entity);
	     root.put("module", module.getModuleName());
	     
	   
		
	     root.put("searchConditionList", getUIComponent(serachConditionDto));
	     root.put("searchDtoList", getUIComponent(entityDto));
	     
	     //输出
	     Writer out = new FileWriter(module.getJspPath()+"\\"+entity.getLowerName()+"Manage.jsp");
	     template.process(root,out);  
	}
	
	
	public void genQueryJs(Configuration cfg,Module module,String templateFile,EntityDesc entity,Class<?> serachConditionDto,Class<?> entityDto) throws IOException, TemplateException{
		 Template template =  cfg.getTemplate(templateFile);  
		 //输入
	     Map<String,Object> root = new HashMap<String,Object>();  
	     root.put("entity",entity);
	     root.put("module", module.getModuleName());
	     
	   
		
	     root.put("searchConditionList", getUIComponent(serachConditionDto));
	     EntityDesc dto = new EntityDesc(entityDto,"");
	     if(dto.getId()== null){
	    	 throw new RuntimeException("查询返回的DTO:"+dto.getPackageName()+"没有定义ID");
	     }
	     root.put("searchDto", dto );
	     //输出
	     Writer out = new FileWriter(module.getJsPath()+"\\"+entity.getLowerName()+"_query.js");
	     template.process(root,out);  
	}
	
	/**
	 * 根据注解的描述 生成UIDesc 
	 * @param entity
	 * @return
	 */
	public  List<UIDesc> getUIComponent(Class<?> entity){
		   List<UIDesc> uiList = new ArrayList<UIDesc>();
		    
		    Field thisFields[] = entity.getDeclaredFields();
		    Class<?> superClass = entity.getSuperclass();
		    Field[] superFields= superClass.getDeclaredFields();
		  
		    List<Field> fields = new ArrayList<Field>();
		    
		    fields.addAll(Arrays.asList(thisFields));
		    if(!"com.wsq.common.dto.Condition".equals(superClass.getName())){
		    	 fields.addAll(Arrays.asList(superFields));
		    }
			for (Field me : fields) {
				Annotation[] ans = me.getAnnotations();
				for (Annotation annotation : ans) {
					if (annotation instanceof FiledComment) {
					    
						FiledComment comment = (FiledComment) annotation;
						UIDesc ui = new UIDesc();
						ui.setCn_name(comment.value());
						ui.setCompontId( me.getName());
						String uiType  = (comment.uiType()) ;
						ui.setUiType(uiType);
						
						if(uiType.equals(UIType.AUTOCOMPLATE)){
							ui.setTextField(comment.textField());
							ui.setValueField(comment.valueField());
							ui.setUrl(comment.ajaxURL());
							ui.setParam(comment.ajaxParam());
						}
						if(uiType.equals(UIType.BASICCONF)){
							ui.setTextField(comment.textField());
							ui.setValueField(comment.valueField());
						}
						
						if(uiType.equals(UIType.SELECT)){
							ui.setTextField(comment.textField());
							ui.setValueField(comment.valueField());
							
							UIDesc option1 = new UIDesc();
							option1.setTextField("中奖");
							option1.setValueField("0");
							
							UIDesc option2 = new UIDesc();
							option2.setTextField("未中奖");
							option2.setValueField("9");
							
							ui.getChildren().add(option1);
							ui.getChildren().add(option2);
						}
						
						uiList.add(ui) ;
					}
				}
			}
			return uiList;
	}
	
	
}
